package cn.wolfcode.web.advice;

import cn.wolfcode.qo.JsonResult;
import com.alibaba.fastjson.JSON;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 对控制器进行增强处理
 * 在进入请求映射方法之前做功能增强: 经典做法: date日期格式化
 * 在进入请求映射方法之后做功能增强: 经典做法: 统一异常处理
 */
@ControllerAdvice
public class GlobalExceptionAdvice {
    /**
     * 该方法是用于捕获并处理某种异常
     * e：现在出现的异常对象
     * method：现在出现异常的那个处理方法
     *
     *当登录出现异常时,
     * login--->抛异常(请求转发)---->handlerException
     * 本质还请求映射方法
     */

    // 处理异常的方法要贴这个注解
    @ExceptionHandler(RuntimeException.class)
    public String handlerException(Model model, RuntimeException e, HandlerMethod handlerMethod,
                                   HttpServletRequest request, HttpServletResponse response) {
        e.printStackTrace(); // 方便开发的时候找 bug

        // 若原本控制器的方法是返回 JSON，现在出异常也应该返回 JSON
        // 获取当前出现异常的方法，判断是否有 ResponseBody 注解，有就代表需要返回 JSON
        ResponseBody annotation = handlerMethod.getMethodAnnotation(ResponseBody.class);
        if (annotation != null) {
            try {
                JsonResult jsonResult = new JsonResult(false, "系统异常,请联系管理员");
                response.setContentType("application/json;charset=utf-8");
                PrintWriter writer = response.getWriter();
                writer.write(JSON.toJSONString(jsonResult));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return null;
        }
        model.addAttribute("errorMsg", e.getMessage());
        // 若原本控制器的方法是返回 HTML，现在也应该返回 HTML
        return "common/error";
    }

}
